//
//  MapViewController.m
//  Stanford Orientation
//
//  Created by Gongmyung on 2/11/10.
//  Copyright 2010 . All rights reserved.
//

#import "MapViewController.h"
#import "StanfordEventsAppDelegate.h"

@implementation MapViewController

@synthesize mapView_;
@synthesize managedObjectContext;
@synthesize refreshButton;
@synthesize needsUpdate;

- (id)initWithArray:(NSMutableArray*)annotations {
    firsttime = YES;
	annotationsArray = annotations;
	[annotationsArray retain];
	return [super init];
}

- (void)addEvents:(NSArray*)annotations {
	[mapView_ addAnnotations:annotations];
}

- (void)addEvent:(Event*)eventToAdd {
    MapAnnotation *annotation = [[MapAnnotation alloc] initWithEvent:eventToAdd];
    [annotationsArray addObject:annotation];
    [annotation release];
    [self refreshMap];
    //[mapView_ setCenterCoordinate:mapView_.region.center animated:NO];
    //stupid stuff to make it refresh
    //NSArray *temp = mapView_.annotations;
    //[mapView_ removeAnnotations:temp];
    //[mapView_ addAnnotations:annotationsArray];
}

- (void)viewDidLoad {
	[mapView_ addAnnotations:annotationsArray];
	detailButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
	[detailButton retain];
	self.navigationController.navigationBarHidden = YES;
    // Create new SBJSON parser object
    parser = [[SBJSON alloc] init];
    
    if (firsttime == YES) {
        MKCoordinateSpan span = MKCoordinateSpanMake(0.01, 0.02);
        CLLocation *stanford = [[CLLocation alloc] initWithLatitude:37.4241667 longitude:-122.165];
        MKCoordinateRegion region = MKCoordinateRegionMake(stanford.coordinate, span);
        [mapView_ setRegion:region animated:YES];
        [mapView_ regionThatFits:region];
    }

    [mapView_ setShowsUserLocation:YES];
    mapView_.delegate = self;
    
	[super viewDidLoad];
    
    [self refresh];
}

- (IBAction)changeType:(id)sender {
	UISegmentedControl	*type = (UISegmentedControl *)sender;
	NSInteger	index = type.selectedSegmentIndex;
	mapView_.mapType = index;
}

- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control {
	//find what the user selected
	Event *tappedEvent = ((MapAnnotation*)(view.annotation)).thisEvent;
    
    EventDetailTableViewController *eventView = [[EventDetailTableViewController alloc] initWithStyle:UITableViewStyleGrouped withEvent:tappedEvent setHidden:YES];
    [self.navigationController pushViewController:eventView animated: YES];
	self.navigationController.navigationBarHidden = NO;
    [eventView release];
}

- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation
{
    if(annotation == mapView_.userLocation) {
        return nil; // this will make sure the pulsing blue thingy is displayed for your location
    }
    
	MKPinAnnotationView *pin = (MKPinAnnotationView *) [mapView dequeueReusableAnnotationViewWithIdentifier: @"mapPin"];
	//MKAnnotationView *pin = (MKPinAnnotationView *) [mapView dequeueReusableAnnotationViewWithIdentifier: @"mapPin"];
	if (pin == nil) {
		pin = [[[MKPinAnnotationView alloc] initWithAnnotation: annotation reuseIdentifier: @"mapPin"] autorelease];
	}
	else {
		pin.annotation = annotation;
	}
	pin.pinColor = MKPinAnnotationColorRed;
	pin.animatesDrop = NO;
	pin.canShowCallout = YES;
    pin.calloutOffset = CGPointMake(-5, 5);
    
	pin.rightCalloutAccessoryView = detailButton;
	/*
     pin.image = [UIImage imageWithData:[((MapAnnotation*)annotation).photoData valueForKey:@"file"]];
     pin.bounds = CGRectMake(0, 0, 32, 32);
     pin.contentMode = UIViewContentModeScaleAspectFit;
     */
	return pin;
}

- (void) centerAtLatitude:(double)lat longitude:(double)lon withSelected:(int)eid {
    //pop the view controller above this one if one exists
    if( self.navigationController.viewControllers.count > 1 ) {
        [self.navigationController setNavigationBarHidden:YES animated:NO];
        [self.navigationController popViewControllerAnimated:NO];
    }
    
    firsttime = NO;
    MKCoordinateSpan span = MKCoordinateSpanMake(0.01, 0.02);
    CLLocation *eventLocation = [[CLLocation alloc] initWithLatitude:lat longitude:lon];
    MKCoordinateRegion region = MKCoordinateRegionMake(eventLocation.coordinate, span);
    [mapView_ setRegion:region animated:YES];
    [mapView_ regionThatFits:region];
    
    //set the event selected
    for (id<MKAnnotation> currentAnnotation in mapView_.annotations) {
        if( [currentAnnotation isKindOfClass: [MapAnnotation class]] ) {
            if( [((MapAnnotation*)currentAnnotation).thisEvent.eid intValue] == eid ) [mapView_ selectAnnotation:currentAnnotation animated:FALSE];
        }
    }
}

/*
 *delegate methods
 */

- (void)mapView:(MKMapView *)mapView didAddAnnotationViews:(NSArray *)views {
    for (MKAnnotationView *annotationView in views) {
        if (annotationView.annotation == mapView.userLocation && firsttime == YES) {
            MKCoordinateSpan span = MKCoordinateSpanMake(0.01, 0.02);
            MKCoordinateRegion region = MKCoordinateRegionMake(mapView.userLocation.coordinate, span);
            [mapView setRegion:region animated:YES];
			[mapView regionThatFits:region];
            firsttime = NO;
        }
    }
}


- (void)mapViewDidFinishLoadingMap:(MKMapView *)mapView {

    /*
    //set all annotations selected
    for (id<MKAnnotation> currentAnnotation in mapView.annotations) {
        [mapView selectAnnotation:currentAnnotation animated:FALSE];
    }
     */
}

- (IBAction)refresh {
    refreshButton.enabled = NO;
    refreshButton.alpha = 0.5f;
    NSMutableArray *stuff = [[NSMutableDictionary alloc] init];
    [stuff setValue:[NSNumber numberWithDouble:mapView_.region.center.latitude] forKey:@"latitude"];
    [stuff setValue:[NSNumber numberWithDouble:mapView_.region.center.longitude] forKey:@"longitude"];
    [stuff setValue:[NSNumber numberWithDouble:mapView_.region.span.latitudeDelta] forKey:@"delta"];
    
    /*
    //before we fire the thread, get the last entry in our principal list stream and send the id
    NSString *username, *password;
    NSUserDefaults *defaultSettings = [NSUserDefaults standardUserDefaults];
    username = [defaultSettings stringForKey:@"username"];
    password = [defaultSettings stringForKey:@"password"];
    
    NSURL *url = [NSURL URLWithString:@"http://colby.stanford.edu/community_vibe/concierge/rpc.php"];
    ASIFormDataRequest *principalRequest = [ASIFormDataRequest requestWithURL:url];
    [principalRequest setPostValue:username forKey:@"name"];
    [principalRequest setPostValue:password forKey:@"key"];
    [principalRequest setPostValue:@"getPrincipalInterestStream" forKey:@"do"];
    [principalRequest setPostValue:@"" forKey:@"since"];    
    [principalRequest setPostValue:@"1" forKey:@"limit"];
    [principalRequest startSynchronous];
    NSString *response;
    NSError *error = [principalRequest error];
    if (!error) {
        response = [principalRequest responseString];
        //NSLog(response);
    }
    NSArray *jsonResponse = [parser objectWithString:response];
    if (jsonResponse.count != 0) {
        NSDictionary *mid = [jsonResponse objectAtIndex:0];
        [stuff setValue:[mid objectForKey:@"mid"] forKey:@"lastmid"];
    }
    else {
        [stuff setValue:@"1" forKey:@"mid"];
    }
     */
    [NSThread detachNewThreadSelector:@selector(startDownload:) toTarget:self withObject:stuff];
}

/*
 * Method that's called when the download is finished
 */
- (void)downloadFinished:(NSString*)eventsToParse {
    NSError *error;
    NSLog(@"About to add downloaded events to map view");
    [eventsToParse retain];
    
    NSArray *messages = [parser objectWithString:eventsToParse];
    for (NSString *message in messages) {
        NSLog(@"parsing message: %@", message);
        NSArray *jsonResponseArray = [parser objectWithString:eventsToParse];
        NSDictionary *jsonResponseDict = [jsonResponseArray objectAtIndex:0];
        NSString *taglist = [jsonResponseDict objectForKey:@"taglist"];
        NSString *eventDataString = [jsonResponseDict objectForKey:@"content"];
        NSLog(@"message has content: %@", eventDataString);
        NSLog(@"message has taglist: %@", taglist);
        
        /*
        NSString *searchForMe = @"Howdi";
        NSRange range = [searchThisString rangeOfString : searchForMe];
        
        if (range.location != NSNotFound) {
            NSLog(@"I found something.");
        }
         */
        //fix later[taglist     [taglist hasPrefix:@"response, stanford_events"]
        if( eventDataString.length > 0 ) {
            NSDictionary *eventData = [parser objectWithString:eventDataString];
            NSFetchRequest *request = [[[NSFetchRequest alloc] init] autorelease];
            [request setEntity:[NSEntityDescription entityForName:@"Event" inManagedObjectContext:managedObjectContext]];
            [request setPredicate:[NSPredicate predicateWithFormat:@"eid==%@", [eventData objectForKey:@"eid"]]];
            NSArray *results = [managedObjectContext executeFetchRequest:request error:&error];
            if( results.count == 0 ) {
                Event *event = (Event *)[NSEntityDescription insertNewObjectForEntityForName:@"Event" inManagedObjectContext:managedObjectContext];
                
                [event setTitle:[eventData objectForKey:@"title"]];
                [event setEid:[NSNumber numberWithDouble:[[eventData objectForKey:@"eid"] doubleValue]]];
                [event setEventdescription:[eventData objectForKey:@"description"]];
                [event setEventtype:[NSNumber numberWithDouble:[[eventData objectForKey:@"eventtype"] doubleValue]]];
                [event setHost:[eventData objectForKey:@"host"]];
                [event setStarttime:[NSDate dateWithTimeIntervalSince1970:[[eventData objectForKey:@"starttime"] doubleValue]]];
                [event setEndtime:[NSDate dateWithTimeIntervalSince1970:[[eventData objectForKey:@"endtime"] doubleValue]]];
                [event setLocation:[eventData objectForKey:@"location"]];
                [event setLatitude:[NSNumber numberWithDouble:[[eventData objectForKey:@"latitude"] doubleValue]]];
                [event setLongitude:[NSNumber numberWithDouble:[[eventData objectForKey:@"longitude"] doubleValue]]];
                [event setCreated:[NSDate dateWithTimeIntervalSince1970:[[eventData objectForKey:@"created"] doubleValue]]];
                MapAnnotation *annotation = [[MapAnnotation alloc] initWithEvent:event];
                [annotationsArray addObject:annotation];
                
                //if event is close enough to be in the nearby events table, push it into the table
                double x = (mapView_.userLocation.coordinate.latitude-[event.latitude doubleValue])*69.1;
                double y = (mapView_.userLocation.coordinate.longitude-[event.longitude doubleValue])*69.1;
                double dist = sqrt( x*x+y*y );
                if ( dist < 0.8 ) {
                    StanfordEventsAppDelegate *appDelegate = (StanfordEventsAppDelegate*)[[UIApplication sharedApplication] delegate];
                    [appDelegate.localEventsListViewController addEvent:event];
                }
            }
        }
    }
    
    if (![managedObjectContext save:&error]) {
        NSLog(@"failed to save created event");
    }
    
    [eventsToParse release];
    [self refreshMap];
}

- (void)updateFilters {
    NSLog(@"Filters updated");
}

//refresh the map
- (void) refreshMap {
    //stupid stuff to make it refresh
    NSArray *temp = mapView_.annotations;
    [mapView_ removeAnnotations:temp];
    [mapView_ setCenterCoordinate:mapView_.region.center animated:YES];
    [mapView_ addAnnotations:annotationsArray];
    [mapView_ setShowsUserLocation:NO];
    [mapView_ setShowsUserLocation:YES];
    
    /*
     //set all annotations selected
     for (id<MKAnnotation> currentAnnotation in mapView.annotations) {
     [mapView selectAnnotation:currentAnnotation animated:FALSE];
     }
     */
}

/*
 * Method for downloading in background thread
 */
- (void)startDownload:(NSMutableDictionary*)stuff {
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    
    //set state to 1 so we know how to respond when we get a push
    StanfordEventsAppDelegate *appDelegate = (StanfordEventsAppDelegate*)[[UIApplication sharedApplication] delegate];
    appDelegate.state = 1;
    NSLog(@"Set application state to 1");
    
    NSString *username, *password;
    NSUserDefaults *defaultSettings = [NSUserDefaults standardUserDefaults];
    username = [defaultSettings stringForKey:@"username"];
    password = [defaultSettings stringForKey:@"password"];
    
    NSMutableDictionary *requestDict = [[NSMutableDictionary alloc] init];
    [requestDict setObject:[stuff objectForKey:@"latitude"] forKey:@"latitude"];
    [requestDict setObject:[stuff objectForKey:@"longitude"] forKey:@"longitude"];
    //one degree of latitude = 69 miles, do a simple conversion here (divide by 2 for radius):
    [requestDict setObject:[NSNumber numberWithDouble:[[stuff objectForKey:@"delta"] doubleValue]*69/1.5] forKey:@"radius"];
    [requestDict setObject:[NSNumber numberWithDouble:[[NSDate date] timeIntervalSince1970]] forKey:@"starttime"];
    [requestDict setObject:[NSNumber numberWithDouble:[[NSDate date] timeIntervalSince1970]] forKey:@"endtime"];
    
    //parse object into json
    SBJSON *sparser = [[SBJSON alloc] init];
    NSString *jsonEvent = [sparser stringWithObject:requestDict];

    //create a get request
    NSURL *url = [NSURL URLWithString:@"http://colby.stanford.edu/community_vibe/concierge/rpc.php"];
    ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:url];
    
    [request setPostValue:username forKey:@"name"];
    [request setPostValue:password forKey:@"key"];
    [request setPostValue:@"postMessage" forKey:@"do"];
    [request setPostValue:jsonEvent forKey:@"content"];    
    [request setPostValue:@"stanford_events,find" forKey:@"tags"];
    NSLog(@"Sending map update request to concierge");
    [request startSynchronous];
    
    NSString *response;
    NSError *error = [request error];
    if (!error) {
        response = [request responseString];
        //NSLog(response);
    }
    
    //start listening for a notification that we have recieved&downloaded a push
    //[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(downloadFinished:) name:@"MapPushRecieved" object:nil];
    
    /*
    //check our concierge principle until we get a response, if nothing after 10 seconds quit
    int count = 0;
    ASIFormDataRequest *principalRequest = [ASIFormDataRequest requestWithURL:url];
    NSString *lastEvent = [stuff objectForKey:@"lastmid"];
    while ( count < 5 ) {
        [NSThread sleepForTimeInterval:1];
        
        [principalRequest setPostValue:username forKey:@"name"];
        [principalRequest setPostValue:password forKey:@"key"];
        [principalRequest setPostValue:@"getPrincipalInterestStream" forKey:@"do"];
        [principalRequest setPostValue:lastEvent forKey:@"since"];    
        [principalRequest setPostValue:@"10" forKey:@"limit"];
        [principalRequest startSynchronous];
        
        error = [principalRequest error];
        if (!error) {
            response = [principalRequest responseString];
        }
        //if we have a response, parse it and add events
        if( response.length != 0 ) {
            NSArray *jsonResponse = [sparser objectWithString:response];
            
            //make sure we have stuff in the response
            if ( jsonResponse.count != 0 ) {
                NSDictionary *jsonResponseDict = [jsonResponse objectAtIndex:0];
                NSString *taglist = [jsonResponseDict objectForKey:@"taglist"];
                if( [taglist hasPrefix:@"response, stanford_events"] ) {
                    NSString *eventDataString = [jsonResponseDict objectForKey:@"content"];
                    NSArray *eventData = [sparser objectWithString:eventDataString];
                    [self performSelectorOnMainThread:@selector(downloadFinished:) withObject:eventData waitUntilDone:NO];
                    break;
                }
            }
        }
        
        count += 1;
    }
     
     */

    [sparser release];
    [stuff release];
    [requestDict release];
    [pool release]; 
}
/*
- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation {
    NSLog(@"hello");
    if( firsttime ) {
        MKCoordinateSpan span = MKCoordinateSpanMake(0.01, 0.02);
        MKCoordinateRegion region = MKCoordinateRegionMake(userLocation.coordinate, span);
        [mapView setRegion:region animated:YES];
        [mapView regionThatFits:region];
        firsttime = NO;
    }
}
*/

- (void)dealloc {
	[mapView_ release];
	[annotationsArray release];
	[detailButton release];
    [parser release];
	[super dealloc];
}

@end
